package com.homework.serviceImpl;

import com.homework.UserServerHandler;
import com.homework.conn.ZkConn;
import com.homework.decoder.RpcDecoder;
import com.homework.pojo.RpcRequest;
import com.homework.service.UserService;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.string.StringEncoder;
import org.springframework.stereotype.Service;

@Service
public class UserServiceImpl implements UserService {

    private static String rootPath = "/netty_rpc";

    private static Integer nettyPort;

    @Override
    public String sayHello(String word) {
        //每调用一次,记录一下时间戳
        long currentTime = System.currentTimeMillis() / 1000;
        //先获取上一次响应时间,如果大于5s则设置为null
        Object prevTime = ZkConn.getZkClient().readData(rootPath + "/p:" + nettyPort);

        System.out.println("prevTime = "+prevTime);

        //刚刚启动,还未被调用过
        if ("start".equalsIgnoreCase(prevTime.toString())){
            ZkConn.getZkClient().writeData(rootPath+"/p:"+nettyPort,currentTime);
        }else {
            long interval = currentTime - Long.parseLong(prevTime.toString());
            if (interval > 5){
                ZkConn.getZkClient().writeData(rootPath+"/p:"+nettyPort,null);
            }else{
                ZkConn.getZkClient().writeData(rootPath+"/p:"+nettyPort,currentTime);
            }
        }
        System.out.println("get client message="+word);
        return "success";
    }

    public static void startServer(String host,Integer port) {
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        ServerBootstrap bootstrap = new ServerBootstrap();

        bootstrap.group(bossGroup,workerGroup)
                .channel(NioServerSocketChannel.class)
                .option(ChannelOption.SO_BACKLOG,1024)
                .childHandler(new ChannelInitializer<SocketChannel>() {
            @Override
            protected void initChannel(SocketChannel socketChannel) throws Exception {
                ChannelPipeline pipeline = socketChannel.pipeline();
                JSONSerializer jsonSerializer = new JSONSerializer();
                pipeline.addLast(new RpcDecoder(RpcRequest.class,jsonSerializer));
                pipeline.addLast(new StringEncoder());
                pipeline.addLast(new UserServerHandler());
            }
        });
        try{
            nettyPort = port;

            System.out.println("netty服务启动成功,host="+host+",port="+port);

            //向zookeeper注册自己
            ZkConn.getZkClient().createEphemeral(rootPath+"/p:"+port,"start");

            ChannelFuture future = bootstrap.bind(host, port).sync();
            //等待服务器socket关闭
            future.channel().closeFuture().sync();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }
}
